React Suspense ressursdeduplisering: Forhindre dupliserte forespørsler | MLOG | MLOG

Nå sjekker UserResource om en ressurs allerede finnes i cache. Hvis den gjør det, returneres den mellomlagrede ressursen. Ellers startes en ny forespørsel, og det resulterende promiset lagres i cachen. Dette sikrer at bare én forespørsel gjøres for hver unike userId.

2. Bruk av et dedikert cache-bibliotek (f.eks. `lru-cache`)

For mer komplekse cache-scenarier, bør du vurdere å bruke et dedikert cache-bibliotek som lru-cache eller lignende. Disse bibliotekene tilbyr funksjoner som fjerning av cache-elementer basert på "Least Recently Used" (LRU) eller andre policyer, noe som kan være avgjørende for å håndtere minnebruk, spesielt når man jobber med et stort antall ressurser.

Først, installer biblioteket:

            
npm install lru-cache

            

Deretter integrerer du det i din UserResource:

            
import React, { Suspense } from 'react';
import LRUCache from 'lru-cache';

const fetchUser = (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Simulate network request
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id: userId, name: `User ${userId}`, email: `user${userId}@example.com` });
    }, 1000); // Simulate network latency
  });
};

const cache = new LRUCache({
  max: 100, // Maximum number of items in the cache
  ttl: 60000, // Time-to-live in milliseconds (1 minute)
});

const UserResource = (userId) => {
  if (!cache.has(userId)) {
    let promise = null;
    let status = 'pending'; // pending, success, error
    let result;

    const suspender = fetchUser(userId).then(
      (r) => {
        status = 'success';
        result = r;
        cache.set(userId, {
          read() {
            return result;
          },
        });
      },
      (e) => {
        status = 'error';
        result = e;
        cache.set(userId, {
          read() {
            throw result;
          },
        });
      }
    );

    cache.set(userId, {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        }
    });
  }

  return cache.get(userId);
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Denne tilnærmingen gir mer kontroll over cachens størrelse og utløpspolicy.

3. Sammenslåing av forespørsler (Request Coalescing) med biblioteker som `axios-extensions`

Biblioteker som axios-extensions tilbyr mer avanserte funksjoner som sammenslåing av forespørsler (request coalescing). Request coalescing kombinerer flere identiske forespørsler til en enkelt forespørsel, noe som ytterligere optimaliserer nettverksbruken. Dette er spesielt nyttig i scenarier der forespørsler initieres svært tett på hverandre i tid.

Først, installer biblioteket:

            
npm install axios axios-extensions

            

Deretter konfigurerer du Axios med cache-adapteren som leveres av axios-extensions.

Eksempel med bruk av `axios-extensions` og opprettelse av en ressurs:

            
import React, { Suspense } from 'react';
import axios from 'axios';
import { cacheAdapterEnhancer, throttleAdapterEnhancer } from 'axios-extensions';

const instance = axios.create({
  baseURL: 'https://api.example.com', // Replace with your API endpoint
  adapter: cacheAdapterEnhancer(axios.defaults.adapter, { enabledByDefault: true }),
});

const fetchUser = async (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Simulate network request
  const response = await instance.get(`/users/${userId}`);
  return response.data;
};


const UserResource = (userId) => {
    let promise = null;
    let status = 'pending'; // pending, success, error
    let result;

    const suspender = fetchUser(userId).then(
        (r) => {
            status = 'success';
            result = r;
        },
        (e) => {
            status = 'error';
            result = e;
        }
    );

    return {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        },
    };
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Dette konfigurerer Axios til å bruke en cache-adapter, som automatisk mellomlagrer svar basert på forespørselskonfigurasjonen. cacheAdapterEnhancer-funksjonen gir alternativer for å konfigurere cachen, som å sette en maksimal cache-størrelse eller utløpstid. throttleAdapterEnhancer kan også brukes for å begrense antall forespørsler som gjøres til serveren innenfor en viss tidsperiode, noe som ytterligere optimaliserer ytelsen.

Beste praksis for ressursdeduplisering

Globale hensyn for datahenting og deduplisering

Når man designer strategier for datahenting for et globalt publikum, er det flere faktorer som spiller inn:

For eksempel kan et reisebestillingsnettsted rettet mot et globalt publikum bruke et CDN for å levere data om fly- og hotelltilgjengelighet fra servere i forskjellige regioner. Nettstedet vil også bruke en API for valutakonvertering for å vise priser i brukerens lokale valuta og tilby alternativer for å filtrere søkeresultater basert på språkpreferanser.

Konklusjon

Ressursdeduplisering er en essensiell optimaliseringsteknikk for React-applikasjoner som bruker Suspense. Ved å forhindre dupliserte datahentingsforespørsler kan du forbedre ytelsen betydelig, redusere serverbelastningen og forbedre brukeropplevelsen. Enten du velger å implementere en enkel promise-cache eller benytte deg av mer avanserte biblioteker som lru-cache eller axios-extensions, er nøkkelen å forstå de underliggende prinsippene og velge løsningen som best passer dine spesifikke behov. Husk å ta hensyn til globale faktorer som CDN-er, lokalisering og tilgjengelighet når du designer datahentingsstrategier for et mangfoldig publikum. Ved å implementere disse beste praksisene kan du bygge raskere, mer effektive og mer brukervennlige React-applikasjoner.